package cn.jsu.oj.dispatchServer.init;

import cn.jsu.oj.dispatchServer.dataStructure.MessageQueue;
import cn.jsu.oj.dispatchServer.factory.CmdHandleFactory;
import cn.jsu.oj.dispatchServer.handle.CommandPack;
import cn.jsu.oj.dispatchServer.net.DispatchServerHandle;
import cn.jsu.oj.dispatchServer.pojo.AbstractPack;
import cn.jsu.oj.dispatchServer.pojo.ResponseBlankPackInfo;
import cn.jsu.oj.dispatchServer.pojo.checkinfo.AbsCheckInfo;
import cn.jsu.oj.dispatchServer.utils.NetUtil;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;


/**
 * @author ahtonc
 */

@Slf4j
public class ClientInitVector {

    private AbstractClientInit init;
    private Channel channel;
    private MessageQueue<Object> messageQueue;

    public ClientInit getInit() {
        return init;
    }

    public void setInit(AbstractClientInit init) {
        this.init = init;
    }

    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

    public MessageQueue<Object> getMessageQueue() {
        return messageQueue;
    }

    public void setMessageQueue(MessageQueue<Object> messageQueue) {
        this.messageQueue = messageQueue;
    }

    public void init(Channel channel) {
        this.channel = channel;
        messageQueue = new MessageQueue<>(100);
    }

    public void addTask(Object object) {
        try {
            messageQueue.put(object);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void close() {
        if (init != null) {
            Object[] ipAndPort = NetUtil.getIpAndPort(channel);
            log.info("容器关闭 IP:" + ipAndPort[0] + " PORT:" + ipAndPort[1]);
            init.close();
        } else {
            log.info("容器关闭 init is empty");
        }
    }

    public void run() {
        try {
            AbstractPack pack = (AbstractPack) messageQueue.take();
            CommandPack<?> commandPack = new CommandPack<>(channel, pack);
            CommandPack<?> cmdPack = CmdHandleFactory.getHandle(pack.getTypeNo()).handle(commandPack);
            Object[] ipAndPort = NetUtil.getIpAndPort(channel);
            if (cmdPack == null) {
                log.info("客户端验证失败 IP:" + ipAndPort[0] + " PORT:" + ipAndPort[1]);
                channel.close();
                return;
            }
            String ip = NetUtil.getIp(channel);
            String realIdentity = ip + "-" + ((AbsCheckInfo) pack).realPort;

            DispatchServerHandle.realIdentityMap.put(NetUtil.getIdentify(channel),realIdentity);
            DispatchServerHandle.vectorMap.put(realIdentity,DispatchServerHandle.vectorMap.remove(NetUtil.getIdentify(channel)));
            log.info("发送验证包 IP:" + ipAndPort[0] + " PORT:" + ipAndPort[1]);
            //发送
            channel.writeAndFlush(new ResponseBlankPackInfo().serialize());
            AbstractClientInit init = (AbstractClientInit) cmdPack.getData();
            init.setChannel(channel);
            init.setMessageQueue(messageQueue);
            this.init = init;
            init.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
